package cn.nekocode.badge;

import ohos.agp.components.AttrHelper;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.Text;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;

public class BadgeDrawable implements Component.DrawTask {
    private String mText1;
    private String mText2;
    private String mNumber;
    private int mBadgeType = 1;

    private float offsetX = 0;
    private float offsetY = 0;

    private int mTextSize;

    private Color mBadgeColor;
    private Color mTextColor;

    private Paint mPaint;

    private int mDefaultFontSize = 16;

    private Context context;

    public static final int TYPE_NUMBER = 1;
    public static final int TYPE_ONLY_ONE_TEXT = 1 << 1;
    public static final int TYPE_WITH_TWO_TEXT = 1 << 2;
    public static final int TYPE_WITH_TWO_IMAGE = 1 << 4;
    public static final int TYPE_WITH_TWO_TEXT_COMPLEMENTARY = 1 << 3;

    private Text mText;
    private Image mImage;

    public static BadgeDrawable Builder(Context context, Text text){
        return new BadgeDrawable(context, text);
    }

    public static BadgeDrawable Builder(Context context, Image image){
        return new BadgeDrawable(context, image);
    }

    public BadgeDrawable(Context context, Text text) {
        this.context = context;
        mText = text;
        init();
    }

    public BadgeDrawable(Context context, Image image) {
        this.context = context;
        mText = new Text(context);
        mImage = image;
        init();
    }

    public void init(){
        mTextColor = Color.WHITE;
        mBadgeColor = Color.YELLOW;

        mPaint = new Paint();
        mPaint.setTextAlign(TextAlignment.CENTER);
        setTextSize(mDefaultFontSize, Text.TextSizeType.FP);
    }

    public BadgeDrawable setTextSize(int size, Text.TextSizeType type){
        mText.setTextSize(size, type);

        if(mImage != null){
            switch(type){
                case FP: mTextSize = AttrHelper.fp2px(size, context); break;
                case PX: mTextSize = size; break;
                case VP: mTextSize = AttrHelper.vp2px(size, context); break;
                default: break;
            }
        }

        return this;
    }

    public BadgeDrawable setNumber(int number){
        mNumber = (number+"").length() > 2 ? "...":number+"";
        return this;
    }

    public BadgeDrawable setText1(String text){
        mText1 = text;
        return this;
    }

    public BadgeDrawable setText2(String text){
        mText2 = text;
        return this;
    }

    public BadgeDrawable setBadgeColor(Color badgeColor){
        mBadgeColor = badgeColor;
        return this;
    }

    public BadgeDrawable setTextColor(Color textColor){
        mTextColor = textColor;
        return this;
    }

    public BadgeDrawable setBadgeType(int badgeType){
        mBadgeType = badgeType;
        return this;
    }

    public boolean build(){
        if(mText1 == null && mText2 == null && mNumber == null){
            return false;
        }
        switch (mBadgeType){
            case TYPE_NUMBER: mText.setText(" " + mNumber + " "); break;
            case TYPE_ONLY_ONE_TEXT: mText.setText(" " + mText1 + " "); break;
            default: mText.setText(" " + mText1 + mText2 + " ");
        }

        if(mImage != null){
            mImage.addDrawTask(this);
            return true;
        }

        mText.addDrawTask(this);
        return true;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        int width = component.getWidth();
        int height = component.getHeight();
        if(component instanceof Image) {
            mPaint.setTextSize(mTextSize);
            offsetX = (width - mPaint.measureText(mText.getText()))/2;
            offsetY = (height - mTextSize - AttrHelper.fp2px(6, context))/(float)2;
            mPaint.setTextSize(mTextSize);
            width -= offsetX;
            height -= offsetY;
        }else{
            mTextSize = mText.getTextSize();
            mPaint.setTextSize(mTextSize);
        }

        switch (mBadgeType){
            case TYPE_NUMBER: drawTypeNumber(width, height, canvas); break;
            case TYPE_ONLY_ONE_TEXT: drawTypeOneText(width, height, canvas); break;
            case TYPE_WITH_TWO_TEXT: drawTypeTwoText(width, height, canvas); break;
            case TYPE_WITH_TWO_TEXT_COMPLEMENTARY: drawTypeTwoTextComplement(width, height, canvas); break;
            case TYPE_WITH_TWO_IMAGE:drawTypeTwoImage(width, height, canvas); break;
        }
    }

    public void drawTypeNumber(int width, int height, Canvas canvas){
        float radius = width / 2.0f > height/2.0f ? height/2.0f : width / 2.0f;
        RectFloat rectFloatBg = new RectFloat(0,0, width, height);
        mPaint.setColor(mBadgeColor);
        canvas.drawCircle(width/2.0f, height/2.0f, radius, mPaint);
        mPaint.setColor(mTextColor);
        canvas.drawText(mPaint, mNumber, rectFloatBg.getCenter().getPointX(), height*3/4.0f);
     }
    public void drawTypeOneText(int width, int height, Canvas canvas){
        mPaint.setColor(mBadgeColor);
        float radius = mTextSize /(float) 5;
        RectFloat rectFloatBg = new RectFloat(offsetX,offsetY, width, height);
        canvas.drawRoundRect(rectFloatBg, radius,radius, mPaint);
        mPaint.setColor(mTextColor);
        canvas.drawText(mPaint, mText1, rectFloatBg.getCenter().getPointX() , height*3/4.0f);
    }

    public void drawTypeTwoText(int width, int height, Canvas canvas){
        float radius = mTextSize / 5f;
        float stockWidth = mTextSize / 8f;

        mPaint.setColor(mTextColor);
        RectFloat rectFloatBg = new RectFloat(offsetX, offsetY, width, height);
        canvas.drawRoundRect(rectFloatBg, radius,radius, mPaint);

        float leftWidth = (mPaint.measureText(mText1) / mPaint.measureText(mText1 + mText2)) * width;

        RectFloat rectFloatL = new RectFloat(offsetX, offsetY, width, height);
        mPaint.setColor(mBadgeColor);
        canvas.drawRoundRect(rectFloatL, radius, radius, mPaint);

        mPaint.setColor(mTextColor);
        RectFloat rectFloatR = new RectFloat(offsetX + leftWidth - stockWidth, offsetY + stockWidth, width - stockWidth, height - stockWidth);
        canvas.drawRoundRect(rectFloatR, stockWidth, stockWidth, mPaint);

        RectFloat rectFloatM = new RectFloat(offsetX + leftWidth - stockWidth,0, leftWidth, height);
        mPaint.setColor(mBadgeColor);
        canvas.drawRoundRect(rectFloatM, 0, 0, mPaint);

        mPaint.setColor(mTextColor);
        canvas.drawText(mPaint, mText1, offsetX + leftWidth/2.0f, height*3/4.0f);

        mPaint.setColor(mBadgeColor);
        canvas.drawText(mPaint, mText2, rectFloatR.getCenter().getPointX() + stockWidth/2.0f, height*3/4.0f);
    }
    public void drawTypeTwoImage(int width, int height, Canvas canvas){
        float radius = mTextSize / 5f;
        float stockWidth = mTextSize / 8f;

        mPaint.setColor(mTextColor);

        RectFloat rectFloatBg = new RectFloat(offsetX, offsetY, width, height);
        canvas.drawRoundRect(rectFloatBg, radius,radius, mPaint);

        float leftWidth = (mPaint.measureText(mText1) / mPaint.measureText(mText1 + mText2)) * (width - offsetX);

        RectFloat rectFloatL = new RectFloat(offsetX, offsetY, width, height);
        mPaint.setColor(mBadgeColor);
        canvas.drawRoundRect(rectFloatL, radius, radius, mPaint);

        mPaint.setColor(mTextColor);
        RectFloat rectFloatR = new RectFloat(offsetX + leftWidth - stockWidth, offsetY + stockWidth, width - stockWidth, height - stockWidth);
        canvas.drawRoundRect(rectFloatR, stockWidth, stockWidth, mPaint);

        RectFloat rectFloatM = new RectFloat(offsetX + leftWidth - stockWidth,0, leftWidth, height);
        mPaint.setColor(mBadgeColor);
        canvas.drawRoundRect(rectFloatM, 0, 0, mPaint);

        mPaint.setColor(mTextColor);
        canvas.drawText(mPaint, mText1, offsetX + leftWidth/2.0f, offsetY + (height - offsetY)*3/4.0f);

        mPaint.setColor(mBadgeColor);
        canvas.drawText(mPaint, mText2, rectFloatR.getCenter().getPointX() + stockWidth/2.0f, offsetY + (height - offsetY)*3/4.0f);
    }

    public void drawTypeTwoTextComplement(int width, int height, Canvas canvas){
        float radius = mTextSize / 5f;
        float stockWidth = mTextSize / 8f;

        mPaint.setColor(mBadgeColor);
        RectFloat rectFloatBg = new RectFloat(offsetX, offsetY, width, height);
        canvas.drawRoundRect(rectFloatBg, radius,radius, mPaint);

        float leftWidth = (mPaint.measureText(mText1)/ mPaint.measureText(mText1 + mText2)) * width;

        RectFloat rectFloatSmall = new RectFloat(offsetX + stockWidth, offsetY + stockWidth, width - stockWidth, height - stockWidth);
        mPaint.setColor(mTextColor);
        canvas.drawRoundRect(rectFloatSmall, stockWidth, stockWidth, mPaint);

        RectFloat rectFloatM = new RectFloat(offsetX + leftWidth - stockWidth/2.0f, offsetY, offsetX + leftWidth + stockWidth/2.0f, height);
        mPaint.setColor(mBadgeColor);
        canvas.drawRoundRect(rectFloatM, 0, 0, mPaint);

        mPaint.setColor(mBadgeColor);
        canvas.drawText(mPaint, mText1, offsetX + (leftWidth + stockWidth/2.0f)/2.0f, height*3/4.0f);
        canvas.drawText(mPaint, mText2,  ( width - leftWidth - 1.5f * stockWidth)/2  + leftWidth, height*3/4.0f);

    }

}

